/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package newkfp;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import javax.ejb.EJB;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import pojos.Treausry;

/**
 *
 * @author $alama
 */
public abstract class AbstractFacade<T> {

    private Class<T> entityClass;
    private Double billTotal, billCach, billRemain, billDisCount;
    @EJB
    private newkfp.CustomerFacade customerFacad;
    @EJB
    private newkfp.ExporterFacade exporterFacad;

    public AbstractFacade(Class<T> entityClass) {
        this.entityClass = entityClass;
    }

    protected abstract EntityManager getEntityManager();

    public void create(T entity) {
        getEntityManager().persist(entity);
    }

    public void edit(T entity) {
        getEntityManager().merge(entity);
    }

    public void remove(T entity) {
        getEntityManager().remove(getEntityManager().merge(entity));
    }

    public T find(Object id) {
        return getEntityManager().find(entityClass, id);
    }

    public List<T> findAll() {
        javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
        cq.select(cq.from(entityClass));
        return getEntityManager().createQuery(cq).getResultList();
    }

    public List<T> findRange(int[] range) {
        javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
        cq.select(cq.from(entityClass));
        javax.persistence.Query q = getEntityManager().createQuery(cq);
        q.setMaxResults(range[1] - range[0]);
        q.setFirstResult(range[0]);
        return q.getResultList();
    }

    public int count() {
        javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
        javax.persistence.criteria.Root<T> rt = cq.from(entityClass);
        cq.select(getEntityManager().getCriteriaBuilder().count(rt));
        javax.persistence.Query q = getEntityManager().createQuery(cq);
        return ((Long) q.getSingleResult()).intValue();
    }

    public List getBillsCustomer(int customerId) {
        Query query = getEntityManager().createNamedQuery("Customer.findByCustomerID");
        System.out.println("customerID:" + customerId);
        Customer t = new Customer(customerId);
        query.setParameter("customerID", t);

        List list = query.getResultList();
        System.out.println("list size:" + list.size());
        return list;
    }

    public List getBillsExporter(int exporterId) {
        Query query = getEntityManager().createNamedQuery("Bill.findByExporterID");

        Exporter t = new Exporter(exporterId);
        query.setParameter("exporterID", t);

        List list = query.getResultList();
        System.out.println(" in list size in facad " + list.size());
        for (Iterator it = list.iterator(); it.hasNext();) {
            Bill object = (Bill) it.next();
            System.out.println(" in facad : " + object.getBillTotal());

        }
        return list;
    }

    public List getItems(int itemNumber) {
        Query query = getEntityManager().createNamedQuery("Item.findByItemType");
        query.setParameter("itemType", itemNumber);

        List list = query.getResultList();
        return list;
    }

    public List getItemsByBillId(int billID) {
        Query query = getEntityManager().createNamedQuery("BillItem.findByBillID");
        Bill bill = new Bill(billID);
        query.setParameter("billID", bill);

        List list = query.getResultList();
        return list;
    }

    public List getCountries(String subItemName) {
        Query query = getEntityManager().createNamedQuery("Item.findByItemName");
        query.setParameter("itemName", subItemName);

        List list = query.getResultList();
        return list;
    }

    public List getFactories(String subItemName, String country) {
        Query query = getEntityManager().createNamedQuery("Item.findByItemNameAndCountry");
        List list = null;
        if (country != null) {
            int id = Integer.parseInt(country);
            Country c = new Country(id);
            query.setParameter("countryID", c);
            query.setParameter("itemName", subItemName);
            list = query.getResultList();
        }

        return list;
    }

    public Exporter getExporterByName(String name) {
        Exporter Ex = null;
        Query query = getEntityManager().createNamedQuery("Exporter.findByExporterByName");
        query.setParameter("exporterName", name);
        List list = query.getResultList();

        if (!(list.size() == 0)) {
            Ex = (Exporter) list.get(0);
        } else {
//            Exporter tiariExporter = new Exporter();
//            tiariExporter.setBalance(0D);
//            tiariExporter.setExporterName(name);
//            tiariExporter.setExporterCode(name);
//            exporterFacad.create(tiariExporter);
//            Ex = tiariExporter;

        }

        return Ex;

    }

    public List<Country> getAllCountry() {
        Query query = getEntityManager().createNamedQuery("Country.findAll");
        List list = query.getResultList();
        return list;
    }

    public List<Exporter> getFactoryByExporterId(int exporterId) {
        Query query = getEntityManager().createNamedQuery("Exporter.findFactoryByExporterId");
        query.setParameter("idexporter", exporterId);
        List list = query.getResultList();
        return list;
    }

    public List<Exporter> getCountryByExporterId(int exporterId) {
        Query query = getEntityManager().createNamedQuery("Exporter.findCountryByExporterId");
        query.setParameter("idexporter", exporterId);
        List list = query.getResultList();
        return list;
    }

    public List<Customer> getCustomerByNameOrID(String name) {
        Query query = getEntityManager().createNamedQuery("Customer.findByCustomerNameOrID");
        query.setParameter("customerName", "%" + name + "%");
        List list = query.getResultList();
        return list;
    }

    public List<Exporter> getExporterByNameOrID(String name) {
        Query query = getEntityManager().createNamedQuery("Exporter.findByExporterNameExporterCode");
        query.setParameter("inputValue", name + "%");
        List list = query.getResultList();
        return list;
    }

    public List<Customer> getCustomerByID(String name) {

        Query query = getEntityManager().createNamedQuery("Customer.findByIdCustomer");
        query.setParameter("idCustomer", name + "%");
        List list = query.getResultList();
        return list;
    }

    public Customer getCustomerByName(String name) {
        Customer customer = null;
        Query query = getEntityManager().createNamedQuery("Customer.findByCustomerByName");
        query.setParameter("customerName", name);
        System.out.println(" customer name is :::::::::::::" + name);


        if (!query.getResultList().isEmpty()) {
            System.out.println(" CUSTOMMMMERRRRR FOUND ");
            customer = (Customer) query.getSingleResult();
        } else {
//            System.out.println(" CUSTOMMER NOT FOUND CREATING ANOTHERRRRRRRRRRRRRRR");
//            Customer tiariCustomer = new Customer();
//            tiariCustomer.setTempFlag(0);
//            tiariCustomer.setCustomerName(name);
//            tiariCustomer.setBalance(0D);
//            tiariCustomer.setCustomerCode(name);
//            tiariCustomer.setAddress(" ");
//            customerFacad.create(tiariCustomer);
//            System.out.println(" CUSTOMMMER CREATEDDDDDDDDDDDDDDDDDDDDDDDDDDD");
//            customer = tiariCustomer;
        }
        return customer;
    }

    public List<ExporterCountry> getCountriesByExporterId(Integer exporterId) {

        Query query = getEntityManager().createNamedQuery("ExporterCountry.findByExporterId");
        Exporter ex = new Exporter(exporterId);
        query.setParameter("idExporter", ex);
        List list = query.getResultList();
        return list;
    }
    ///////////////////////// factory Function /////////////////////
    public Factory getFactoryById(int id) {
        Query query = getEntityManager().createNamedQuery("Factory.findByIdFactory");
        query.setParameter("idFactory", id);
        List list = query.getResultList();
        if (list == null) {
            System.out.println(" list null in getting factory  ");
            return null;

        }
        return (Factory) list.get(0);
    }

    public Factory getFactoryByName(String name) {
        Query query = getEntityManager().createNamedQuery("Factory.findByFactoryName");
        query.setParameter("factoryName", name);
        List list = query.getResultList();
        if (list == null) {
            System.out.println(" list null in getting factory  ");
            return null;
        }
        return (Factory) list.get(0);
    }
    // ----------------country function ------------------////////////////////////////////

    public Country getCountryById(int id) {
        Query query = getEntityManager().createNamedQuery("Country.findByIdcountry");
        query.setParameter("idcountry", id);
        List list = query.getResultList();
        if (list == null) {
            System.out.println(" list null in getting country  ");
            return null;
        }
        return (Country) list.get(0);
    }

    public List<Factory> getFactoryOfCountryById(Country id) {
        Query query = getEntityManager().createNamedQuery("Factory.findByIdCountry");
        query.setParameter("idcountry", id);
        List<Factory> list = query.getResultList();

        return list;
    }

    public Country getCountryByName(String name) {
        Query query = getEntityManager().createNamedQuery("Country.findByCountryName");
        query.setParameter("countryName", name);
        List list = query.getResultList();
        if (list == null) {
            System.out.println(" list null in getting country  ");
            return null;
        }
        return (Country) list.get(0);
    }

    public ExporterItem getExporterItemByItemId(int idItem, int factoryId) {
        Query query = getEntityManager().createNamedQuery("ExporterItem.findByIdItem");
        Item i = new Item(idItem);
        query.setParameter("itemID", i);
        Factory f = new Factory(factoryId);
        query.setParameter("factoryID", f);
        List list = query.getResultList();
        if (list == null) {
            System.out.println(" list null in getting exporter Item ");
            return null;
        }
        return (ExporterItem) list.get(0);
    }

    public List<BillItem> getCustomerBillAtPeriod(int id, Date from, Date to) {
        //System.out.println("From: "+from +" To: "+to);
        billTotal = 0.0;
        billCach = 0.0;
        billRemain = 0.0;
        billDisCount = 0.0;
        ArrayList<BillItem> billItems = new ArrayList<BillItem>();
        Query query = getEntityManager().createNamedQuery("Bill.findByCustomerIDAtPeriod");
        Customer c = new Customer(id);
        System.out.println("id : " + c.getIdCustomer());
        query.setParameter("customerID", c);
        query.setParameter("createDateFrom", from);
        query.setParameter("createDateTo", to);
        List list = query.getResultList();
        System.out.println("List Size: " + list.size());
        for (Iterator it = list.iterator(); it.hasNext();) {
            Bill bill = (Bill) it.next();
            billItems.addAll(bill.getBillItemCollection());
            billTotal += bill.getBillTotal();
            billCach += bill.getBillCach();
            billRemain += bill.getBillReminder();

            billDisCount += bill.getDisCount();
        }
        return billItems;
    }

    public List<BillItem> getExporterBillAtPeriod(int id, Date from, Date to) {
        //System.out.println("From: "+from +" To: "+to);
        billTotal = 0.0;
        billCach = 0.0;
        billRemain = 0.0;
        billDisCount = 0.0;
        ArrayList<BillItem> billItems = new ArrayList<BillItem>();
        Query query = getEntityManager().createNamedQuery("Bill.findByExporterIDAtPeriod");
        Exporter e = new Exporter(id);
        query.setParameter("exporterID", e);
        query.setParameter("createDateFrom", from);
        query.setParameter("createDateTo", to);
        List list = query.getResultList();
        System.out.println("List Size: " + list.size());
        for (Iterator it = list.iterator(); it.hasNext();) {
            Bill bill = (Bill) it.next();
            billItems.addAll(bill.getBillItemCollection());
            billTotal += bill.getBillTotal();
            billCach += bill.getBillCach();
            billRemain += bill.getBillReminder();
            billDisCount += bill.getDisCount();
        }
        return billItems;
    }

    public List<BillItem> getNotConfirmedBillAtPeriod( Date from, Date to) {
        Query query = getEntityManager().createNamedQuery("Bill.findNotConfirmedBills");
        query.setParameter("createDateFrom", from);
        query.setParameter("createDateTo", to);
        List list = query.getResultList();
        System.out.println("Not Confirmed List Size: "+list.size());
        return list;
    }

    public Double getBillCach() {
        return billCach;
    }

    public void setBillCach(Double billCach) {
        this.billCach = billCach;
    }

    public Double getBillDisCount() {
        return billDisCount;
    }

    public void setBillDisCount(Double billDisCount) {
        this.billDisCount = billDisCount;
    }

    public Double getBillRemain() {
        return billRemain;
    }

    public void setBillRemain(Double billRemain) {
        this.billRemain = billRemain;
    }

    public Double getBillTotal() {
        return billTotal;
    }

    public void setBillTotal(Double billTotal) {
        this.billTotal = billTotal;
    }

    public List<Bill> getNotConfirmedCusromerBill() {

        Query query = getEntityManager().createNamedQuery("Bill.findNotConfirmedCusromerBill");
        Exporter ex = new Exporter(-1);
        query.setParameter("exporterID", ex);
        List list = query.getResultList();
        return list;
    }

    public List<Bill> getNotConfirmedExporterBill() {

        Query query = getEntityManager().createNamedQuery("Bill.findNotConfirmedExporterBill");
        Customer c = new Customer(-1);
        query.setParameter("customerID", c);
        List list = query.getResultList();
        return list;
    }

    public List<Bill> billCheck(int billNumber, int docNum,Date d) {
        Query query = getEntityManager().createNamedQuery("Bill.check");
        query.setParameter("billNumber", billNumber);
        query.setParameter("docNum", docNum);
        query.setParameter("exporterID", new Exporter(-1));
        query.setParameter("createDate", d);
        List list = query.getResultList();
        return list;
    }

    public List<Bill> billCheckexporter(int billNumber, int docNum,Date d) {
        Query query = getEntityManager().createNamedQuery("Bill.checkExporter");
        query.setParameter("billNumber", billNumber);
        query.setParameter("docNum", docNum);
        query.setParameter("customerID", new Customer(-1));
        query.setParameter("createDate", d);
        List list = query.getResultList();
        return list;
    }

    public List<BillItem> getBillItems(int id) {
        Query query = getEntityManager().createNamedQuery("BillItem.findByBillID");
        Bill bill = new Bill(id);
        query.setParameter("billID", bill);
        List list = query.getResultList();
        return list;
    }


 public List<Treausry> getTreasuryAtPeriod( Date from, Date to) {
        Query query = getEntityManager().createNamedQuery("Treausry.findByActionDatePariod");
        query.setParameter("createDateFrom", from);
        query.setParameter("createDateTo", to);
        List list = query.getResultList();
        System.out.println("Not Confirmed List Size: "+list.size());
        return list;
    }

}
